package filechain

import (
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"strconv"
)

//定义区块链结构
type Block struct {
	Index        int
	Timestamp    string
	PreviousHash string
	content      map[string]interface{}
}

//var filechain [][]string
//var  tempChain []string
//构造并获取
func (B *Block) setIndex(index int) {
	B.Index = index
}
func (B *Block) getIndex() string {
	in := fmt.Sprintf("%d", B.Index)
	return in
}

func (B *Block) setTimestamp(time string) {
	B.Timestamp = time
}
func (B *Block) getTimestamp() string {
	return B.Timestamp
}

func (B *Block) setPreviousHash(pre string) {
	B.PreviousHash = pre
}
func (B *Block) getPreviousHash() string {
	return B.PreviousHash
}
func (B *Block) setContent(m map[string]interface{}) {
	B.content = m
}
func (B *Block) getContent() string {
	m := fmt.Sprintf("%s", B.content)
	return m
}

//josin 转 map
func (B *Block) strToMap(result string) map[string]interface{} {
	var dat map[string]interface{}
	if err := json.Unmarshal([]byte(result), &dat); err == nil {
		fmt.Println("==============json str 转map=======================")
		//fmt.Println(dat)
	}
	return dat
}

//josin 转 map2
func (B *Block) strToMapTwo(result string) map[string]interface{} {
	var a map[string]interface{}
	return a
}

//创建区块
func (B *Block) CreateBlock(index int, time string, PreviousHash string, content map[string]interface{}) (int, []string) {

	if index == 0 {

		//NowTime := time2.Now()
		B.setTimestamp(time)
		//fmt.Println(NowTime)
		B.setIndex(index)
		/*contents := map[string]string{
			"email": "Hello World!",
		}*/
		B.setContent(content)

		B.setPreviousHash(PreviousHash)
		/*fmt.Println(
			B.getIndex(),
			B.getTimestamp(),
			B.getPreviousHash(),
			B.getContent(),
		)*/
		m := map[string]string{
			"Index":        B.getIndex(),
			"Timestamp":    B.getTimestamp(),
			"PreviousHash": B.getPreviousHash(),
			"Content":      B.getContent(),
		}
		//fmt.Println("index :",m["Index"])
		tempChain := make([]string, 4)
		tempChain[0] = fmt.Sprintf("{\"%s\":\"%s\"}", "Index", m["Index"])
		tempChain[1] = fmt.Sprintf("{\"%s\":\"%s\"}", "Timestamp", m["Timestamp"])
		tempChain[2] = fmt.Sprintf("{\"%s\":\"%s\"}", "PreviousHash", m["PreviousHash"])
		tempChain[3] = fmt.Sprintf("{\"%s\":\"%s\"}", "Content", m["Content"])
		/*var i = 0
		for k ,v := range m{
			tempChain[i]=fmt.Sprintf("%s : %s" , k ,v)
			fmt.Printf("%s   %s___> %d    ",k , v ,i)
			i = i+1
		}*/
		/*for k, v := range tempChain {
			fmt.Println(k, v)
		}*/
		index = index + 1
		return index, tempChain
	} else {
		//NowTime := time2.Now()

		B.setTimestamp(time)
		//fmt.Println(NowTime)
		B.setIndex(index)
		//contents := content
		B.setContent(content)
		B.setPreviousHash(PreviousHash)
		/*fmt.Println(
			B.getIndex(),
			B.getTimestamp(),
			B.getPreviousHash(),
			B.getContent(),
		)*/
		m := map[string]string{
			"Index":        B.getIndex(),
			"Timestamp":    B.getTimestamp(),
			"PreviousHash": B.getPreviousHash(),
			"Content":      B.getContent(),
		}
		//fmt.Println("index :",m["Index"])
		tempChain := make([]string, 4)
		tempChain[0] = fmt.Sprintf("{\"%s\":\"%s\"}", "Index", m["Index"])
		tempChain[1] = fmt.Sprintf("{\"%s\":\"%s\"}", "Timestamp", m["Timestamp"])
		tempChain[2] = fmt.Sprintf("{\"%s\":\"%s\"}", "PreviousHash", m["PreviousHash"])
		tempChain[3] = fmt.Sprintf("{\"%s\":\"%s\"}", "Content", m["Content"])
		/*var i = 0
		for k ,v := range m{
			tempChain[i]=fmt.Sprintf("%s : %s" , k ,v)
			fmt.Printf("%s   %s___> %d    ",k , v ,i)
			i = i+1
		}*/
		/*for k, v := range tempChain {
			fmt.Println(k, v)
		}*/
		index = index + 1
		return index, tempChain
	}
}

//连接区块
func (B *Block) CreatChain(chain [][]string, temp []string, TempMap map[int]map[string]interface{},
	content map[string]interface{}, data string, email string) (chains [][]string, ID int, emails string, times string, pres string, conents string) {
	/*if len(chaina)==0{
		chain := make([][]string,0)
		//fmt.Println(temp)
		chain = append(chain,temp)
		return chain
	}else*/
	//fmt.Println(len(chain))
	chain = append(chain, temp)
	//fmt.Println(len(chain))
	fmt.Println("添加成功")
	for k, v := range temp {
		dat := B.strToMap(v)
		fmt.Println(k)
		fmt.Println(dat)
		TempMap[k] = dat
	}
	fmt.Println("===============================")
	TempMap[3]["Content"] = data

	IndexDB, emailDB, TimestampDB, PreviousHashDB, ContentDB := TempMap[0]["Index"], email, TempMap[1]["Timestamp"], TempMap[2]["PreviousHash"], TempMap[3]["Content"]
	indexID, err := strconv.Atoi(IndexDB.(string))
	if err != nil {
		println("你需要睡觉了")
	}
	fmt.Printf("%T  %T   %T  %T  %T \n", indexID, emailDB, TimestampDB, PreviousHashDB, ContentDB)
	fmt.Printf("%T  %s   %s  %s  %s \n", IndexDB, emailDB, TimestampDB, PreviousHashDB, ContentDB)
	fmt.Println("===============================")

	return chain, indexID, emailDB, TimestampDB.(string), PreviousHashDB.(string), ContentDB.(string)
}

func (B *Block) GetHash(chain [][]string) string {
	var pre string
	if len(chain) == 0 {
		B.setPreviousHash("0001")
	} else {
		//fmt.Println("file",len(chain))
		NowBlock := chain[len(chain)-1]
		//fmt.Println( NowBlock[0],"最后一个链的数据")
		NowBlockTemp := fmt.Sprintf("%s %s %s %s", NowBlock[0], NowBlock[1], NowBlock[2], NowBlock[3])
		//fmt.Println(NowBlockTemp,"Now 临时 NowBlock")
		hashed := md5.Sum([]byte(NowBlockTemp))
		pre := hex.EncodeToString(hashed[:])
		//fmt.Println("NowBlock md5单向散列为",pre)
		//B.setPreviousHash(pre)
		return pre
	}
	return pre
}
func BlockBuild() *Block {
	var btc = new(Block)
	return btc
}

/*func  ProductionFirstBlock(){
var btc = new(Block)
var chaina [][]string
contents := map[string]string{
	"email": "Hello World!",
}
_,block:=btc.CreateBlock(0,"001",contents)
dataMap :=btc.CreatChain(chaina,block)
fmt.Println(dataMap,"全部链的数据")
NowHash :=btc.GetHash(dataMap)
//fmt.Println("现在的哈希值",NowHash)
_,block1:= btc.CreateBlock(1,NowHash,contents)
dataMap1 :=btc.CreatChain(dataMap,block1)
fmt.Println(dataMap1,"全部链的数据")
}*/
